package cate.game.role.res.racebadge;

import cate.common.table.res.racebadge.row.RaceBadgeBaseRow;
import cate.common.table.res.racebadge.row.RaceBadgeGradeRow;
import cate.common.table.res.racebadge.row.RaceBadgeLevelUpRow;
import cate.common.util.GameResult;
import cate.game.attr.FightAttr;
import cate.game.res.*;
import cate.game.role.Role;
import cate.game.role.RoleDependent;
import cate.game.role.res.racebadge.msg.RaceBadgeUpdateResp;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import org.springframework.data.annotation.Transient;

import java.util.Map;

@NoteClass(value = "单个族徽的数据")
public class RaceBadge extends RoleDependent {
    @NoteField(value = "族徽类型")
    public int type;

    @NoteField(value = "图腾等级")
    public int level;

    @NoteField(value = "当前等级注能次数")
    public int times;

    @NoteField("阶数")
    public int grade;

    public RaceBadge(){}

    public RaceBadge(Role role, int type){
        super(role);
        this.type = type;
        this.level = 0;
    }

    public GameResult<Void> levelUp(){
        GameResult<Void> r = new GameResult<>();
        RaceBadgeLevelUpRow baseRow = role.getGame().table.raceBadge.levelUp.getRowByTypeAndLevel(this.type, this.level);
        if(baseRow == null){
            return r.fail("族徽配置异常");
        }
        RaceBadgeLevelUpRow nextRow = role.getGame().table.raceBadge.levelUp.getRowByTypeAndLevel(type, level + 1);
        if(times * baseRow.value >= baseRow.maxValue &&
                nextRow == null){
            return  r.fail("已经升到最大阶段");
        }
        MixRes consume = new MixRes(baseRow.consumeStr);
        GameResult<MixResItem> consumeRes = consume.consume(role);
        if(!consumeRes.ok()){
            role.getGame().notice.tipResItem(role, consumeRes.data);
            return r.fail(consumeRes.message);
        }
        times ++;
        if(times * baseRow.value >= baseRow.maxValue){
            level ++;
            times = 0;
        }
        noticeUpdate();
        return r;
    }

    public GameResult<Void> gradeUp(Map<Integer, CostSelect> csMap){
        GameResult<Void> r = new GameResult<>();
        RaceBadgeGradeRow baseRow = role.getGame().table.raceBadge.grade.getGradeRow(this.type, this.grade);
        if(baseRow == null){
            return r.fail("族徽配置异常");
        }
        if (baseRow.levelLimit == 0) {
            return r.fail("已经升满拉");
        }
        if (level < baseRow.levelLimit) {
            return r.fail("等级未达到要求");
        }
        GameResult<RewardShow> returnRes = role.getGame().train.hero.checkAndConsume(role, csMap, baseRow.consumeHeroStr, baseRow.consumeItemStr);
        if (!returnRes.ok()) {
            return r.fail(returnRes);
        }
        if (!returnRes.data.isEmpty()) {
            role.getGame().notice.dialog(role, returnRes.data);
        }
        grade ++;
        noticeUpdate();
        return r;
    }

    public void noticeUpdate(){
        role.sendNow(new RaceBadgeUpdateResp(this));
    }

    @JsonIgnore
    public FightAttr getAttr(){
        FightAttr attr = new FightAttr();
        if(level > 0){
            for(int i = 0; i < level; ++i){
                RaceBadgeLevelUpRow levelUpRow = role.getGame().table.raceBadge.levelUp.getRowByTypeAndLevel(type, i);
                if(levelUpRow != null){
                    if(levelUpRow.maxValue > 0){
                        attr.add(new FightAttr(levelUpRow.attrStr).scale(levelUpRow.maxValue / levelUpRow.value));
                    }
                }
            }
        }
        if(times > 0){
            RaceBadgeLevelUpRow levelUpRow = role.getGame().table.raceBadge.levelUp.getRowByTypeAndLevel(type, level);
            if(levelUpRow != null){
                attr.add(new FightAttr(levelUpRow.attrStr).scale(times));
            }
        }
        if (grade > 0) {
            RaceBadgeGradeRow gradeRow = role.getGame().table.raceBadge.grade.getGradeRow(type, grade);
            if (gradeRow != null) {
                attr.add(new FightAttr(gradeRow.attrStr));
                for (Map.Entry<Integer, Double> per : gradeRow.percent.entrySet()) {
                    attr.scale(per.getKey(), 1 + per.getValue());
                }
            }
        }
        return attr;
    }

    @JsonIgnore
    @Transient
    public RaceBadgeBaseRow getRow(){
        return role.getGame().table.raceBadge.base.get(type);
    }
}
